using System;
using System.Threading;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;

namespace OracleInternal.NotificationServices
{
	internal class Subscriber
	{
		private string subscription_Renamed_Field;

		private string component_Renamed_Field;

		private Publisher pub;

		private ONS oems;

		private int id_Renamed_Field;

		protected internal NotificationQueue queue;

		private CallBack cb;

		private int cbmode;

		private object cblock;

		private int numcbthreads;

		public const int CBMODE_ONETHREAD = 1;

		public const int CBMODE_THREADPERCB = 2;

		protected internal virtual int ID
		{
			set
			{
				id_Renamed_Field = value;
			}
		}

		internal Subscriber(ONS o, string s, string c, long timeout)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.ctor);
			}
			try
			{
				oems = o;
				realStartup(s, c, timeout);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.Subscriber, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.ctor);
				}
			}
		}

		private void realStartup(string s, string c, long timeout)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.realStartup);
			}
			try
			{
				subscription_Renamed_Field = s;
				pub = new Publisher(oems, c);
				component_Renamed_Field = c;
				id_Renamed_Field = -1;
				queue = new NotificationQueue(oems);
				oems.addSubscriber(this, timeout);
				cb = null;
				cbmode = 0;
				cblock = new object();
				numcbthreads = 0;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.Subscriber, OracleTraceFuncName.realStartup, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.realStartup);
				}
			}
		}

		public virtual Notification receive(bool blocking)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.receive);
			}
			try
			{
				if (!oems.shutdown_Renamed_Field)
				{
					return (Notification)queue.dequeue(blocking);
				}
				return null;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.Subscriber, OracleTraceFuncName.receive, ex);
				return null;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.receive);
				}
			}
		}

		public virtual void close()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.close);
			}
			try
			{
				if (cb != null)
				{
					cancel_callback();
				}
				oems.removeSubscriber(id_Renamed_Field);
				pub.close();
				queue.close();
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.Subscriber, OracleTraceFuncName.close, ex);
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.close);
				}
			}
		}

		public virtual string subscription()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.subscription);
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.subscription);
			}
			return subscription_Renamed_Field;
		}

		public virtual int id()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.id);
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.id);
			}
			return id_Renamed_Field;
		}

		protected internal virtual void deliver(Notification n)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.deliver);
			}
			try
			{
				if (cb != null && cbmode == 2)
				{
					CallBackThread callBackThread = new CallBackThread(this, cb, n);
					lock (cblock)
					{
						numcbthreads--;
					}
					callBackThread.Start();
				}
				else
				{
					queue.enqueue(n);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.Subscriber, OracleTraceFuncName.deliver, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.deliver);
				}
			}
		}

		public virtual void cancel_callback()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.Subscriber, OracleTraceFuncName.cancel_callback);
			}
			try
			{
				cb = null;
				int num;
				lock (cblock)
				{
					num = numcbthreads;
				}
				while (num > 0)
				{
					try
					{
						SupportClass.ThreadClass.Current();
						Thread.Sleep(new TimeSpan(10000000L));
					}
					catch (Exception ex)
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.Subscriber, OracleTraceFuncName.cancel_callback, "CallBackThread::threadpercb() failed. -" + ex.Message);
						}
					}
					lock (cblock)
					{
						num = numcbthreads;
					}
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.Subscriber, OracleTraceFuncName.cancel_callback, ex2);
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.Subscriber, OracleTraceFuncName.cancel_callback);
				}
			}
		}
	}
}
